package com.mew.common.dc.db;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mew.common.config.RedisConstantValue;
import com.mew.common.dc.mapper.GameMapper;
import com.mew.common.dc.mapper.RoomMapper;
import com.mew.common.enm.DataStateType;
import com.mew.common.entity.config.Game;
import com.mew.common.entity.config.Room;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 下线的游戏， 直接从redis 移除 ；  如果房间关闭完了 则游戏也自动关闭
 * 房间下线： 直接从房间列表移除
 * @Author King.Song
 * @Date 2020/11/23 0023
 **/
@Service
@Slf4j
public class GameRoomService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private GameMapper gameMapper;
    @Autowired
    private RoomMapper roomMapper;
    @Autowired
    private DefaultRedisScript<Long> roomProfileScript;


    //下线的游戏， 直接从redis 移除 ；  如果房间关闭完了 则游戏也自动关闭
    public void loadRoomGame()throws Exception{
        redisTemplate.delete(RedisConstantValue.GAMECONF_GAME);
        LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<Game>()
                .eq(Game::getState, DataStateType.Active.code());
        List<Game> list = gameMapper.selectList(queryWrapper);
    }

    //下线的游戏， 直接从redis 移除 ；  如果房间关闭完了 则游戏也自动关闭
    public void loadRoomGame(List<Integer> gameIds)throws Exception{
        List<Game> list = gameMapper.selectBatchIds(gameIds);
    }


    public Game getRedisGame(int gameId){
        if (gameId <1){
            return null;
        }
        return  (Game) redisTemplate.opsForHash().get(RedisConstantValue.GAMECONF_GAME, gameId);
    }




    private int loadRoom(int gameId){
        LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<Room>()
                .eq(Room::getGameId, gameId)
                .eq(Room::getState, DataStateType.Active.code());
        List<Room> list = roomMapper.selectList(queryWrapper);
        if (null == list || list.isEmpty()){
            return 0;
        }


        String roomKey = String.format(RedisConstantValue.GAMECONF_ROOM_LIST, gameId);
        redisTemplate.delete(roomKey);
        list.forEach(room -> redisTemplate.opsForList().leftPush(roomKey, room));
        return list.size();
    }




    public List<Room> findRoomAllByDB(){
        LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<Room>()
                .eq(Room::getState, DataStateType.Active.code());
        return roomMapper.selectList(queryWrapper);
    }

    public List<Room> findRoomByGameId(int gameId){
        if (gameId <1){
            return null;
        }
        List<Object> list = redisTemplate.opsForList().range(String.format(RedisConstantValue.GAMECONF_ROOM_LIST, gameId), 0, -1);
        if (null == list || list.isEmpty()){
            return null;
        }
        return list.stream().map(o -> (Room)o).collect(Collectors.toList());
    }

    public Room getRedisRoom(int gameId, int roomId){
        if (roomId <1){
            return null;
        }
        List<Room> list = findRoomByGameId(gameId);
        if (null == list || list.isEmpty()){
            return null;
        }
        return list.stream().filter(r -> roomId == r.getId()).findFirst().orElse(null);
    }


    public void updateRoom(Room room){
        roomMapper.updateById(room);
    }


    public void updateRedisRoom(Room room){
        List<Object> list = redisTemplate.opsForList().range(String.format(RedisConstantValue.GAMECONF_ROOM_LIST, room.getGameId()), 0, -1);
        if (null == list || list.isEmpty()){
            return;
        }

        int index = -1;
        Room tr;
        for (int i=0; i<list.size(); i++){
            tr = (Room) list.get(i);
            if (room.equals(tr)){
                index = i;
                break;
            }
        }

        if (index == -1){
            return;
        }
        redisTemplate.opsForList().set(String.format(RedisConstantValue.GAMECONF_ROOM_LIST, room.getGameId()), index, room);
    }




    public long doLua(int roomId, long betNumber, long paymentNumber,
                      long temp_blood_n,
                      long balance_end_n, int small_end_n, int big_end_n,
                      int plan_type_n,
                      double small_wave_fold, double big_wave_fold,
                      long wave_cheat){
        long res =  redisTemplate.execute(roomProfileScript, Arrays.asList(String.valueOf(roomId)), betNumber, paymentNumber,
                1000000, temp_blood_n, 0,
                balance_end_n, small_end_n, big_end_n,
                plan_type_n,
                small_wave_fold, big_wave_fold,
                wave_cheat
        );
        return res;
    }

    public long doLua(long gameId, long betNumber){
        long res =  redisTemplate.execute(roomProfileScript, Arrays.asList(String.valueOf(gameId)), betNumber);
        return res;
    }





}

